package com.atguigu.tingshu.album.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.config.MinioConstantProperties;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.AlbumStatService;
import com.atguigu.tingshu.common.constant.RabbitConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatMqVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.minio.DeleteObjectTagsArgs;
import io.minio.MinioClient;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

	@Autowired
	private AlbumInfoMapper albumInfoMapper;
	@Autowired
	private AlbumAttributeValueService albumAttributeValueService;
	@Autowired
	private AlbumStatService albumStatService;
	@Autowired
	private MinioConstantProperties minioConstantProperties;
	@Autowired
	private RabbitTemplate rabbitTemplate;
	@Autowired
	private RedisTemplate<String,String> redisTemplate;
	@Autowired
	private RedissonClient redissonClient;

	@Override
	@Transactional
	public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {

		AlbumInfo albumInfo = new AlbumInfo();
		Long userId = AuthContextHolder.getUserId();
		albumInfo.setUserId(userId);
		albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
		BeanUtils.copyProperties(albumInfoVo, albumInfo);

		//  付费的默认前5集免费看
		String payType = albumInfoVo.getPayType();
		if(!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(payType)) {		// 专辑是付费类型
			albumInfo.setTracksForFree(5);
		}

		albumInfoMapper.insert(albumInfo);

		Long albumId = albumInfo.getId();
		List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
		//将albumAttributeValueVoList转为List<AlbumAttributeValue>
		List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
			AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
			albumAttributeValue.setAlbumId(albumId);
			BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
			return albumAttributeValue;
		}).toList();

		//批量保存
		albumAttributeValueService.saveBatch(albumAttributeValues);

		//存储album_stat表数据
		saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_PLAY);
		saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_SUBSCRIBE);
		saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_BROWSE);
		saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_COMMENT);

		if ("1".equals(albumInfoVo.getIsOpen())){
			rabbitTemplate.convertAndSend(RabbitConstant.SEARCH_EXCHANGE,RabbitConstant.SEARCH_UPPER_QUEUE_KEY,String.valueOf(albumId));
		}

	}

	/**
	 * 分页查询专辑
	 * @param pageNo
	 * @param pageSize
	 * @param albumInfoQuery
	 * @return
	 */
	@Override
	public IPage findUserAlbumPage(Long pageNo, Long pageSize, AlbumInfoQuery albumInfoQuery) {
		albumInfoQuery.setUserId(AuthContextHolder.getUserId());

		Page<AlbumListVo> albumListVoPage = new Page<>(pageNo, pageSize);
		return albumInfoMapper.findUserAlbumPage(albumListVoPage, albumInfoQuery);

	}

	/**
	 * 删除专辑信息
	 * @param id
	 */
	@Override
	@Transactional
	public void removeAlbumInfo(Long id) {
		AlbumInfo albumInfo = albumInfoMapper.selectById(id);
		albumInfoMapper.deleteById(id);

		LambdaQueryWrapper<AlbumAttributeValue> eq = new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, id);
		albumAttributeValueService.remove(eq);

		LambdaQueryWrapper<AlbumStat> eq1 = new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, id);
		albumStatService.remove(eq1);

		//todo:删除minio中图片文件
		deleteCoverUrl(albumInfo.getCoverUrl());

		if ("1".equals(albumInfo.getIsOpen())){
			rabbitTemplate.convertAndSend(RabbitConstant.SEARCH_EXCHANGE,RabbitConstant.SEARCH_LOWER_QUEUE_KEY,String.valueOf(albumInfo.getId()));
		}
	}

	/**
	 * 获取专辑详情
	 * @param albumId
	 * @return
	 */
	@Override
	public AlbumInfo getAlbumInfo(Long albumId) {

		//查询redis之前先查询布隆过滤器看数据是否存在
		RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
		boolean contains = bloomFilter.contains(albumId);
		if (!contains){
			return new AlbumInfo();
		}

		//todo:先查询redis中是否存在
		String key = RedisConstant.ALBUM_INFO_PREFIX+albumId;
		String s = redisTemplate.opsForValue().get(key);
		AlbumInfo albumInfo = JSON.parseObject(s, AlbumInfo.class);
		if (albumInfo != null){
			return albumInfo;
		}
		//todo：不存在，查询数据库

		albumInfo = getAlbumInfoToDB(albumId);

		//todo:存入到redis中
		redisTemplate.opsForValue().set(key,JSON.toJSONString(albumInfo));

		return albumInfo;
	}

	public AlbumInfo getAlbumInfoToDB(Long albumId){
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);

		if (albumInfo != null){
			LambdaQueryWrapper<AlbumAttributeValue> eq = new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId);
			List<AlbumAttributeValue> list = albumAttributeValueService.list(eq);
			albumInfo.setAlbumAttributeValueVoList(list);
		}
		return albumInfo;
	}

	/**
	 * todo: 完善修改专辑信息
	 * @param id
	 * @param albumInfoVo
	 */
	@Override
	public void updateAlbumInfo(Long id, AlbumInfoVo albumInfoVo) {
		AlbumInfo albumInfo = albumInfoMapper.selectById(id);

		//todo: 修改专辑判断专辑封面是否更新 更新就删除minio中保存的图片
		if (!albumInfo.getCoverUrl().equals(albumInfoVo.getCoverUrl())){
			//todo:删除minio中图片文件
			deleteCoverUrl(albumInfo.getCoverUrl());
		}
		BeanUtils.copyProperties(albumInfoVo, albumInfo);
		albumInfoMapper.updateById(albumInfo);

		// 删除之前旧的专辑属性值
		albumAttributeValueService.remove(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, id));

		List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
		List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
			AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
			BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
			albumAttributeValue.setAlbumId(id);
			return albumAttributeValue;
		}).toList();
		//批量保存
		albumAttributeValueService.saveBatch(albumAttributeValues);

		if ("1".equals(albumInfoVo.getIsOpen())){
			rabbitTemplate.convertAndSend(RabbitConstant.SEARCH_EXCHANGE,RabbitConstant.SEARCH_UPPER_QUEUE_KEY,String.valueOf(albumInfo.getId()));
		}else {
			rabbitTemplate.convertAndSend(RabbitConstant.SEARCH_EXCHANGE,RabbitConstant.SEARCH_LOWER_QUEUE_KEY,String.valueOf(albumInfo.getId()));
		}
	}

	@Override
	public List<AlbumInfo> findUserAllAlbumList() {
		Long userId = AuthContextHolder.getUserId();
		LambdaQueryWrapper<AlbumInfo> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(AlbumInfo::getUserId, userId);
		queryWrapper.select(AlbumInfo::getAlbumTitle,AlbumInfo::getId);
		List<AlbumInfo> albumInfos = albumInfoMapper.selectList(queryWrapper);
		return albumInfos;
	}

	private void saveAlbumStat(Long albumId, String statType) {
		AlbumStat albumStat = new AlbumStat();
		albumStat.setAlbumId(albumId);
		albumStat.setStatType(statType);
		albumStat.setStatNum(0);
		albumStatService.save(albumStat);
	}


	public void deleteCoverUrl(String coverUrl){
		 //构建minioClient
        MinioClient minioClient =
          MinioClient.builder()
              .endpoint(minioConstantProperties.getEndpointUrl())
              .credentials(minioConstantProperties.getAccessKey(), minioConstantProperties.getSecreKey())
              .build();
		//获取图片名称
		String[] split = coverUrl.split("/");
		String objectName = split[split.length-1];
		//删除图片
//		DeleteObjectTagsArgs deleteObjectTagsArgs = DeleteObjectTagsArgs.builder().bucket(minioConstantProperties.getBucketName()).object(objectName).build();
		RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(minioConstantProperties.getBucketName()).object(objectName).build();
		try {
			minioClient.removeObject(removeObjectArgs);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("删除图片失败:"+coverUrl);
		}
	}
}

